﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace System
{
    //public static class TConverter
    //{
    //    public static T To<T>(this object value)
    //    {
    //        return (T)To(typeof(T), value);
    //    }
    //    public static T To<T>(this object value, string message)
    //    {
    //        return (T)To(typeof(T), value);
    //    }
    //    public static object To(Type t, object value)
    //    {
    //        TypeConverter tc = TypeDescriptor.GetConverter(t);
    //        return tc.ConvertFrom(value);
    //    }
       
    //    public static void RegisterTypeConverter<T, TC>() where TC : TypeConverter
    //    {

    //        TypeDescriptor.AddAttributes(typeof(T), new TypeConverterAttribute(typeof(TC)));

    //    }

    //}

    public static class Change
    {

        public static T To<T>(this object value)
        {
            return To<T>(value, null);
        }
        public static T To<T>(this object value, string message)
        {
            return To<T>(value, message, null);
        }
        public static T To<T>(this object value, object defaultValue)
        {
            return To<T>(value, null, null);
        }
        public static T To<T>(this object value, string message, object defaultValue)
        {
            try
            {
                Type conversionType = typeof(T);
                if (Convert.IsDBNull(value))
                {
                    value = Convert.DBNull;
                }
                if (conversionType.IsGenericType &&
                    conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
                {
                    if (value == null)
                    {
                        if (defaultValue == null)
                            return default(T);
                        else
                            return To<T>(defaultValue, null);
                    }

                    conversionType = Nullable.GetUnderlyingType(conversionType);
                    return (T)Convert.ChangeType(value, conversionType);
                }
                else
                {
                    return (T)Convert.ChangeType(value, conversionType);
                }
            }
            catch (Exception e)
            {
                if (string.IsNullOrEmpty(message))
                {
                    throw;
                }
                else
                {
                    throw new ApplicationException(message, e);
                }
            }
        }
    }
}

